版权声明:本文为博主原创文章,转载请注明出处:http://blog.jerkybible.com/2015/05/21/Spring MVC 之 @Autowired/
访问原文「Spring MVC 之 @Autowired」
一、准备工作
POJO类Parent
Controller类HomeController
root-context.xml
web.xml略。
二、回忆
在Spring 使用简单Demo进行源码调试(六)这篇文章中介绍了bean参数的赋值,AutoWired也是在这个地方实现自动加载的。首先展开文章中的doCreateBean。这里省略了很多代码。首先看pplyMergedBeanDefinitionPostProcessors这个方法。
断点运行到后去homeController的,后处理为AutowiredAnnotationBeanPostProcessor,如下图。
展开AutowiredAnnotationBeanPostProcessor中的findAutowiringMetadata方法。这一步中的重点是在buildAutowiringMetadata,构建元数据。buildAutowiringMetadata首先去缓存里面找元数据,找不到就遍历bean的和父类的字段域和方法,如果别标记为@Autowired并且不是静态的就添加到InjectionMetadata中,并添加到缓存中。
|
|
三、自动装载
代码运行到populateBean方法。这个方法太长,这里就不贴出来了,直接走到postProcessPropertyValues方法,获得InjectionMetadata对象后便遍历其中的所有InjectionElement对象,调用其中的inject方法。接着对每一个injectedElement进行inject。最后的inject进行真正的属性赋值。
|
|
|
|
看一下resolveDependency。 这个方法其实就是根据类型到bean工厂中查找类型匹配的bean实例,然后就看到了这几个条件分支语句,如果是数组,集合,映射表,自定义类型都执行了差不多的操作,findAutowireCandidate方法。这个方法会去工厂中执行类型匹配的查找,将匹配的结果集返回,不同的是,集合数组类型会通过TypeConverter进行结果的转换。
到此为止,找到了属性的匹配值,然后反射赋值就完成了整个的自动装配过程。可以看出,@Autowired是通过类型来进行自动装配的。
上面是属性的赋值过程也就是InjectionFieldElement的inject方法,InjectionMethodElement的inject方法大致相同只是对每一个方法参数执行一次resolveDependency方法来获取参数值,然后反射执行方法。
到此为止,整个实例化和装配过程也就讲完了,我们总结一下:
1)一切都是从bean工厂的getBean方法开始的,一旦该方法调用总会返回一个bean实例,无论当前是否存在,不存在就实例化一个并装配,否则直接返回。
2)实例化和装配过程中会多次递归调用getBean方法来解决类之间的依赖。
3)Spring几乎考虑了所有可能性,所以方法特别复杂但完整有条理。
4)@Autowired最终是根据类型来查找和装配元素的,但是我们设置了